package com.cfpamf.ms.insur.wx.request;

import com.cfpamf.ms.insur.wx.model.WxPayRefundQueryModel;
import com.cfpamf.ms.insur.wx.model.WxPayRefundCouponInfo;
import com.cfpamf.ms.insur.wx.response.WxPayRefundQueryResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.ResponseHandler;
import org.apache.http.util.EntityUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 提交退款申请后，通过调用该接口查询退款状态。退款有一定延时，用零钱支付的退款20分钟内到账，银行卡支付的退款3个工作日后重新查询退款状态。
 * 微信退款接口
 */
@Slf4j
public class WxPayRefundQueryRequest extends WxAbstractRequest<WxPayRefundQueryModel, WxPayRefundQueryResponse>
        implements WechatPayDownloadRequest<WxPayRefundQueryModel, WxPayRefundQueryResponse> {

    public WxPayRefundQueryRequest(WxPayRefundQueryModel model) {
        super(model);
    }

    @Override
    public String getApiAction() {
        return "/pay/refundquery";
    }

    @Override
    public Class<WxPayRefundQueryModel> getObjectClass() {
        return WxPayRefundQueryModel.class;
    }

    @Override
    public Class<WxPayRefundQueryResponse> getResponseClass() {
        return WxPayRefundQueryResponse.class;
    }

    /**
     *
     */
    @Override
    public boolean requireCert() {
        return false;
    }

    @Override
    public ResponseHandler<WxPayRefundQueryResponse> getResponseHandler(ObjectMapper mapper) {
        return response -> {
            String respContent = EntityUtils.toString(response.getEntity(), "UTF-8");
            WxPayRefundQueryResponse result = mapper.readValue(respContent, getResponseClass());
            result.setContent(respContent);

            Integer refundCount = result.getRefundCount();
            refundCount = Objects.isNull(refundCount) ? 0 : refundCount;
            result.setRefundRecords(Lists.newArrayList());
            if (refundCount > 0) {
                Map<String, Object> map = mapper.readValue(respContent, Map.class);
                WxPayRefundQueryResponse.RefundRecord refundRecord = new WxPayRefundQueryResponse.RefundRecord();

                result.getRefundRecords().add(refundRecord);
                for (int i = 0; i < refundCount; i++) {
                    Object val = map.get("out_refund_no_" + i);
                    refundRecord.setOutRefundNo(Objects.nonNull(val) ? val.toString() : null);

                    val = map.get("refund_id_" + i);
                    refundRecord.setRefundId(Objects.nonNull(val) ? val.toString() : null);

                    val = map.get("refund_channel_" + i);
                    refundRecord.setRefundChannel(Objects.nonNull(val) ? val.toString() : null);
                    val = map.get("refund_fee_" + i);
                    refundRecord.setRefundFee(Integer.parseInt(Objects.nonNull(val) ? val.toString() : "0"));
                    val = map.get("settlement_refund_fee_" + i);
                    refundRecord.setSettlementRefundFee(Integer.parseInt(Objects.nonNull(val) ? val.toString() : "0"));
                    val = map.get("coupon_refund_fee_" + i);
                    refundRecord.setCouponRefundFee(Integer.parseInt(Objects.nonNull(val) ? val.toString() : "0"));
                    val = map.get("coupon_refund_count_" + i);
                    refundRecord.setCouponRefundCount(Integer.parseInt(Objects.nonNull(val) ? val.toString() : "0"));
                    val = map.get("refund_status_" + i);
                    refundRecord.setRefundStatus(Objects.nonNull(val) ? val.toString() : null);
                    val = map.get("refund_recv_accout_" + i);
                    refundRecord.setRefundRecvAccount(Objects.nonNull(val) ? val.toString() : null);
                    val = map.get("refund_success_time_" + i);
                    refundRecord.setRefundSuccessTime(Objects.nonNull(val) ? val.toString() : null);

                    if (refundRecord.getCouponRefundCount() == null || refundRecord.getCouponRefundCount() == 0) {
                        continue;
                    }

                    List<WxPayRefundCouponInfo> coupons = Lists.newArrayList();
                    for (int j = 0; j < refundRecord.getCouponRefundCount(); j++) {

                        WxPayRefundCouponInfo wxPayRefundCouponInfo = new WxPayRefundCouponInfo();
                        coupons.add(wxPayRefundCouponInfo);

                        val = map.get("coupon_refund_id_" + i + "_" + j);
                        wxPayRefundCouponInfo.setCouponRefundId(Objects.nonNull(val) ? val.toString() : null);
                        val = map.get("coupon_refund_fee_" + i + "_" + j);
                        wxPayRefundCouponInfo.setCouponRefundFee(Integer.parseInt(Objects.nonNull(val) ? val.toString() : "0"));
                        val = map.get("coupon_type_" + i + "_" + j);
                        wxPayRefundCouponInfo.setCouponType(Objects.nonNull(val) ? val.toString() : null);
                    }

                    refundRecord.setRefundCoupons(coupons);
                }
            }
            log.info("校验响应数据成功");
            log.info("wx request {}==>\n{}", getApiAction(), respContent);
            return result;
        };
    }
}
